from fastapi import APIRouter, Depends, Query, HTTPException, File, UploadFile
from sqlalchemy.orm import Session
from ..database.db import get_db
from ..crud.paper_crud import (get_paper_page_grade,get_paper_page_subject, get_paper_by_id,
                             create_paper as create_paper_db,
                             update_paper as update_paper_db,
                             delete_paper as delete_paper_db,
                             get_paper_page_grade_subject)
from ..schemas.base import ResponseModel
from pydantic import BaseModel
from enum import Enum
from typing import List, Optional
import os
from dotenv import load_dotenv
from ..utils.jwt_handler import get_username

paper_router = APIRouter(prefix="/paper-operate", tags=["试卷"])

load_dotenv()
SOURCES_PATH = os.getenv("SOURCES_PATH")


class PaperBase(BaseModel):
    id: int
    name: str
    path: str
    type: str
    subject: str
    grade: str
    starts: int
    oss_url: str


class QueryResponseModel(BaseModel):
    papers: List[PaperBase]


class PaperList(ResponseModel):
    data: QueryResponseModel


class PaperDemo(BaseModel):
    paper: PaperBase


class PaperResponseModel(ResponseModel):
    data: PaperDemo


class SubjectEnum(str, Enum):
    chinese = "语文"
    math = "数学"
    english = "英语"
    physics = "物理"
    chemistry = "化学"
    biology = "生物"
    history = "历史"
    geography = "地理"
    politics = "政治"


class GradeEnum(str, Enum):
    seventh_grade = "七年级"
    eighth_grade = "八年级"
    ninth_grade = "九年级"

@paper_router.get("/subject/{subject}", response_model=PaperList)
async def get_papers_by_subject(
        subject: SubjectEnum,
        page: int = Query(1, ge=1),
        page_size: int = Query(10, ge=1, le=100),
        db: Session = Depends(get_db)
):
    """
    根据学科分页获取试卷列表
    """
    papers = get_paper_page_subject(db, subject, page, page_size)
    papers = [paper.as_dict() for paper in papers]
    return {
        "code": 200,
        "message": "ok",
        "data": {
            "papers": papers
        }
    }

@paper_router.get("/grade/{grade}", response_model=PaperList)
async def get_papers_by_grade(
        grade: GradeEnum,
        page: int = Query(1, ge=1),
        page_size: int = Query(10, ge=1, le=100),
        db: Session = Depends(get_db)
):
    """
    根据年级分页获取试卷列表
    """
    papers = get_paper_page_grade(db, grade, page, page_size)
    papers = [paper.as_dict() for paper in papers]
    return {
        "code": 200,
        "message": "ok",
        "data": {
            "papers": papers
        }
    }
@paper_router.get("/grade/{grade}/subject/{subject}", response_model=PaperList)
async def get_papers_by_grade_and_subject(
        grade: GradeEnum,
        subject: SubjectEnum,
        page: int = Query(1, ge=1),
        page_size: int = Query(10, ge=1, le=100),
        db: Session = Depends(get_db)
):
    """
    根据年级和学科分页获取试卷列表
    """
    papers = get_paper_page_grade_subject(db, grade, subject, page, page_size)
    return {
        "code": 200,
        "message": "ok",
        "data": {
            "papers": [paper.as_dict() for paper in papers]
        }
    }


@paper_router.get("/{paper_id}", response_model=PaperResponseModel)
async def get_paper(paper_id: int, db: Session = Depends(get_db)):
    """
    根据ID获取试卷详情
    """
    paper = get_paper_by_id(db, paper_id)
    return {
        "code": 200,
        "message": "ok",
        "data": {
            "paper": paper
        }
    }


@paper_router.post("/", response_model=PaperResponseModel)
async def create_paper(
        subject: SubjectEnum,
        grade: GradeEnum,
        paper_file: UploadFile = File(...),
        db: Session = Depends(get_db),
        username: str = Depends(get_username)
):
    """
    创建一个新的试卷。

    **试卷必须为doc文件**
    """
    if not paper_file.filename.lower().endswith('.doc'):
        raise HTTPException(status_code=400, detail="文件格式错误")

    base_path = "sources/papers/download"
    subject_folder = f"初中{subject.value}"

    file_path_db = base_path + "/" + subject_folder + "/" + paper_file.filename
    download_path = os.path.join(SOURCES_PATH, file_path_db)

    # 确保目录存在
    os.makedirs(os.path.dirname(download_path), exist_ok=True)

    # 保存文件
    try:
        # 读取上传的文件内容
        file_content = await paper_file.read()

        # 写入到指定路径
        with open(download_path, "wb") as buffer:
            buffer.write(file_content)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"文件保存失败: {str(e)}")

    # 重置文件指针，以便后续可能需要再次读取
    await paper_file.seek(0)

    created_paper = create_paper_db(
        db,
        name=paper_file.filename,
        path=file_path_db,
        type="paper",
        subject=subject,
        grade=grade,
        starts=0
    )

    return {
        "code": 200,
        "message": "创建试卷成功",
        "data": {
            "paper": created_paper
        }
    }


@paper_router.put("/{paper_id}", response_model=PaperResponseModel)
async def update_paper(
        paper_id: int,
        subject: SubjectEnum = None,
        grade: GradeEnum = None,
        db: Session = Depends(get_db),
        username: str = Depends(get_username)
):
    """
    更新指定 ID 的试卷信息。

    **只能更新试卷的科目和年级。如果需要其他内容，需重新上传文件**

    **只更新一项时，其余项不用填写**
    """
    # 构造更新数据
    updated_paper = update_paper_db(db, paper_id=paper_id, subject=subject, grade=grade)
    return {
        "code": 200,
        "message": "更新成功",
        "data": {
            "paper": updated_paper
        }
    }

    # 创建一个临时模型来传递数据
    paper_update_data = type('PaperUpdateData', (BaseModel,), update_data)()

    updated_paper = update_paper_db(db, paper_id, paper_update_data)
    return {
        "code": 200,
        "message": "更新成功",
        "data": {
            "paper": updated_paper
        }
    }


@paper_router.delete("/{paper_id}", response_model=PaperResponseModel)
async def delete_paper(paper_id: int, db: Session = Depends(get_db),
                       username: str = Depends(get_username)):
    """
    删除指定 ID 的试卷。
    """
    deleted_paper = delete_paper_db(db, paper_id)
    return {
        "code": 200,
        "message": "删除成功",
        "data": {
            "paper": deleted_paper
        }
    }
